home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
archiver
/
uux789.zoo
/
uud.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-07-06
|
12KB
|
573 lines
/*
* Uud -- decode a uuencoded file back to binary form.
*
* From the Berkeley original, modified by MSD, RDR, JPHD & WLS.
* The Atari GEMDOS version compiled with MWC 2.x.
* The MSDOS version with TurboC.
* The Unix version with cc.
* this version is made: 25 Nov 1988.
*/
/*
* Be sure to have the proper symbol at this point. (GEMDOS, MSDOS, UNIX...)
*/
/*
#ifndef GEMDOS
#define GEMDOS 1
#endif
*/
#ifndef UNIX
#define UNIX 1
#endif
/*
#ifndef MSDOS
#define MSDOS 1
#endif
*/
#ifdef GEMDOS
#define SYSNAME "gemdos"
#define SMALL 1
#endif
#ifdef MSDOS
#define SYSNAME "msdos"
#define SMALL 1
#endif
#ifdef UNIX
#define SYSNAME "unix"
#endif
#include <stdio.h>
#ifdef GEMDOS
#include <osbind.h>
#define Error(n) { Bconin(2); exit(n); }
#define WRITE "wb"
#else
#define Error(n) exit(n)
#define WRITE "w"
#endif
#define loop while (1)
extern FILE *fopen();
extern char *strcpy();
extern char *strcat();
char *getnword();
#define MAXCHAR 256
#define LINELEN 256
#define FILELEN 64
#define NORMLEN 60 /* allows for 80 encoded chars per line */
#define SEQMAX 'z'
#define SEQMIN 'a'
char seqc;
int first, secnd, check, numl;
FILE *in, *out;
char *pos;
char ifname[FILELEN], ofname[FILELEN];
char *source = NULL, *target = NULL;
char blank, part = '\0';
int partn, lens;
int debug = 0, nochk = 0, onedone = 0;
int chtbl[MAXCHAR], cdlen[NORMLEN + 3];
main(argc, argv) int argc; char *argv[];
{
int mode;
register int i, j;
char *curarg;
char dest[FILELEN], buf[LINELEN];
if (argc < 2) {
format("Almost foolproof uudecode v3.4 (%s) 25-Nov-88\n",
SYSNAME);
format("\n");
format("Usage: uud [-n] [-d] [-s dir] [-t dir] input-file\n");
format("\n");
format("Option: -n -> No line sequence check\n");
format("Option: -d -> Debug/verbose mode\n");
format("Option: -s + Source directory for all input files\n");
format(" (MUST be terminated by directory separator)\n");
format("Option: -t + Target directory for all output files\n");
format(" (MUST be terminated by directory separator)\n");
format("If input-file is - then stdin is used as input-file\n");
Error(1);
}
curarg = argv[1];
while (curarg[0] == '-') {
if (((curarg[1] == 'd') || (curarg[1] == 'D')) &&
(curarg[2] == '\0')) {
debug = 1;
} else if (((curarg[1] == 'n') || (curarg[1] == 'N')) &&
(curarg[2] == '\0')) {
nochk = 1;
} else if (((curarg[1] == 't') || (curarg[1] == 'T')) &&
(curarg[2] == '\0')) {
argv++;
argc--;
if (argc < 2) {
format("uud: Missing target directory.\n");
Error(15);
}
target = argv[1];
if (debug)
format("Target dir = %s\n",target);
} else if (((curarg[1] == 's') || (curarg[1] == 'S')) &&
(curarg[2] == '\0')) {
argv++;
argc--;
if (argc < 2) {
format("uud: Missing source directory.\n");
Error(15);
}
source = argv[1];
if (debug)
format("Source dir = %s\n",source);
} else if (curarg[1] != '\0') {
format("uud: Unknown option <%s>\n", curarg);
Error(15);
} else
break;
argv++;
argc--;
if (argc < 2) {
format("uud: Missing file name.\n");
Error(15);
}
curarg = argv[1];
}
if ((curarg[0] == '-') && (curarg[1] == '\0')) {
in = stdin;
strcpy(ifname, "<stdin>");
} else {
if (source != NULL) {
strcpy(ifname, source);
strcat(ifname, curarg);
} else
strcpy(ifname, curarg);
if ((in = fopen(ifname, "r")) == NULL) {
format("uud: Can't open %s\n", ifname);
Error(2);
}
numl = 0;
}
/*
* Set up the default translation table.
*/
for (i = 0; i < ' '; i++) chtbl[i] = -1;
for (i = ' ', j = 0; i < ' ' + 64; i++, j++) chtbl[i] = j;
for (i = ' ' + 64; i < MAXCHAR; i++) chtbl[i] = -1;
chtbl['`'] = chtbl[' ']; /* common mutation */
chtbl['~'] = chtbl['^']; /* an other common mutation */
blank = ' ';
/*
* set up the line length table, to avoid computing lotsa * and / ...
*/
cdlen[0] = 1;
for (i = 1, j = 5; i <= NORMLEN; i += 3, j += 4)
cdlen[i] = (cdlen[i + 1] = (cdlen[i + 2] = j));
/*
* search for header or translation table line.
*/
loop { /* master loop for multiple decodes in one file */
partn = 'a';
loop {
if (fgets(buf, sizeof buf, in) == NULL) {
if (onedone) {
if (debug) format("End of file.\n");
exit(0);
} else {
format("uud: No begin line.\n");
Error(3);
}
}
numl++;
if (strncmp(buf, "table", 5) == 0) {
gettable();
continue;
}
if (strncmp(buf, "begin", 5) == 0) {
break;
}
}
lens = strlen(buf);
if (lens) buf[--lens] = '\0';
#ifdef SMALL
if ((pos = getnword(buf, 3))) {
strcpy(dest, pos);
} else
#else
if(sscanf(buf,"begin%o%s", &mode, dest) != 2)
#endif
{
format("uud: Missing filename in begin line.\n");
Error(10);
}
if (target != NULL) {
strcpy(ofname, target);
strcat(ofname, dest);
} else
strcpy(ofname, dest);
if((out = fopen(ofname, WRITE)) == NULL) {
format("uud: Cannot open output file: %s\n", ofname);
Error(4);
}
if (debug) format("Begin uudecoding: %s\n", ofname);
seqc = SEQMAX;
check = nochk ? 0 : 1;
first = 1;
secnd = 0;
decode();
fclose(out);
#ifdef UNIX
chmod(ofname, mode);
#endif
onedone = 1;
if (debug) format("End uudecoding: %s\n", ofname);
} /* master loop for multiple decodes in one file */
}
/*
* Bring back a pointer to the start of the nth word.
*/
char *getnword(str, n) register char *str; register int n;
{
while((*str == '\t') || (*str == ' ')) str++;
if (! *str) return NULL;
while(--n) {
while ((*str != '\t') && (*str != ' ') && (*str)) str++;
if (! *str) return NULL;
while((*str == '\t') || (*str == ' ')) str++;
if (! *str) return NULL;
}
return str;
}
/*
* Install the table in memory for later use.
*/
gettable()
{
char buf[LINELEN];
register int c, n = 0;
register char *cpt;
for (c = 0; c <= MAXCHAR; c++) chtbl[c] = -1;
again: if (fgets(buf, sizeof buf, in) == NULL) {
format("uud: EOF while in translation table.\n");
Error(5);
}
numl++;
if (strncmp(buf, "begin", 5) == 0) {
format("uud: Incomplete translation table.\n");
Error(6);
}
cpt = buf + strlen(buf) - 1;
*cpt = ' ';
while (*(cpt) == ' ') {
*cpt = 0;
cpt--;
}
cpt = buf;
while (c = *cpt) {
if (chtbl[c] != -1) {
format("uud: Duplicate char in translation table.\n");
Error(7);
}
if (n == 0) blank = c;
chtbl[c] = n++;
if (n >= 64) return;
cpt++;
}
goto again;
}
/*
* copy from in to out, decoding as you go along.
*/
decode()
{
char buf[LINELEN], outl[LINELEN];
register char *bp, *ut;
register int *trtbl = chtbl;
register int n, c, rlen;
register unsigned int len;
loop {
if (fgets(buf, sizeof buf, in) == NULL) {
format("uud: EOF before end.\n");
fclose(out);
Error(8);
}
numl++;
len = strlen(buf);
if (len) buf[--len] = '\0';
/*
* Is it an unprotected empty line before the end line ?
*/
if (len == 0) continue;
/*
* Get the binary line length.
*/
n = trtbl[*buf];
if (n >= 0) goto decod;
/*
* end of uuencoded file ?
*/
if (strncmp(buf, "end", 3) == 0) return;
/*
* end of current file ? : get next one.
*/
if (strncmp(buf, "include", 7) == 0) {
getfile(buf);
continue;
}
format("uud: Bad prefix line %d in file: %s\n",numl, ifname);
if (debug) format("Bad line =%s\n",buf);
Error(11);
/*
* Sequence checking ?
*/
decod: rlen = cdlen[n];
/*
* Is it the empty line before the end line ?
*/
if (n == 0) continue;
/*
* Pad with blanks.
*/
for (bp = &buf[c = len];
c < rlen; c++, bp++) *bp = blank;
/*
* Verify if asked for.
*/
if (debug) {
for (len = 0, bp = buf; len < rlen; len++) {
if (trtbl[*bp] < 0) {
format(
"Non uuencoded char <%c>, line %d in file: %s\n", *bp, numl, ifname);
format("Bad line =%s\n",buf);
Error(16);
}
bp++;
}
}
/*
* All this just to